package com.tiger.project.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.tiger.common.core.domain.model.LoginUser;
import com.tiger.common.core.redis.RedisCache;
import com.tiger.common.exception.CustomException;
import com.tiger.common.utils.Code;
import com.tiger.common.utils.DateUtils;
import com.tiger.common.utils.StringUtils;
import com.tiger.project.domain.*;
import com.tiger.project.domain.req.DepositChange;
import com.tiger.project.domain.vo.ContractSponsorExportVo;
import com.tiger.project.mapper.*;
import com.tiger.project.service.IContractSponsorService;
import com.tiger.system.mapper.SysDeptMapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.Period;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * 【合同发起】Service业务层处理
 *
 * @author standard
 * @date 2022-09-22
 */
@Service
public class ContractSponsorServiceImpl implements IContractSponsorService {
    @Autowired
    private ContractSponsorMapper contractSponsorMapper;
    @Autowired
    private ContractSponsorEnclosureMapper enclosureMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private CommonDecisionMapper decisionMapper;
    @Autowired
    private ContractSponsorAlterMapper alterMapper;
    @Autowired
    private ContractBillMapper billMapper;
    @Autowired
    private AssetReceiptMapper receiptMapper;
    @Resource
    private SysDeptMapper deptMapper;
    @Autowired
    private AssetMapper assetMapper;
    @Autowired
    private ContractSponsorCreditMapper creditMapper;
    @Autowired
    private AssetReceiptAllocationMapper allocationMapper;
    @Autowired
    private BookValueMapper bookValueMapper;

    @Autowired
    private ContractMapper contractMapper;

    /**
     * 查询【合同发起】
     *
     * @param id 【合同发起】主键
     * @return 【合同发起】
     */
    @Override
    public ContractSponsor selectContractSponsorById(Long id) {
        ContractSponsor contractSponsor = contractSponsorMapper.selectContractSponsorById(id);
        //附件
        ContractSponsorEnclosure contractSponsorEnclosure = new ContractSponsorEnclosure();
        contractSponsorEnclosure.setContractSponsorId(id);
        List<ContractSponsorEnclosure> list = enclosureMapper.selectContractSponsorEnclosureList(contractSponsorEnclosure);
        if (list != null && list.size() > 0) {
            contractSponsor.getEnclosureList().addAll(list);
        }
        //决策依据
        String decisionBasisIds = contractSponsor.getDecisionId();
        if (StringUtils.isNotEmpty(decisionBasisIds)) {
            List<String> ids = Arrays.asList(decisionBasisIds.split(","));
            for (String i : ids) {
                CommonDecision decision = decisionMapper.selectCommonDecisionById(Long.valueOf(i));
                contractSponsor.getCommonDecisionList().add(decision);
            }
        }

        // 合同变更的决策依据
        String alterDecisionId = contractSponsor.getAlterDecisionId();
        if (StringUtils.isNotEmpty(alterDecisionId)) {
            List<String> ids = Arrays.asList(alterDecisionId.split(","));
            for (String i : ids) {
                CommonDecision decision1 = decisionMapper.selectCommonDecisionById(Long.valueOf(i));
                contractSponsor.getCommonDecisionList1().add(decision1);
            }
        }


        //历史变更
        ContractSponsorAlter sponsorAlter = new ContractSponsorAlter();
        sponsorAlter.setContractSponsor(id);
        List<ContractSponsorAlter> sponsorAlterList = alterMapper.selectContractSponsorAlterList(sponsorAlter);
        if (sponsorAlterList != null && sponsorAlterList.size() > 0) {
            contractSponsor.getAlterList().addAll(sponsorAlterList);
        }

        //资产
        String assetId = contractSponsor.getAssetId();
        if (StringUtils.isNotEmpty(assetId)) {
            List<String> asList = Arrays.asList(assetId.split(","));
            for (String a : asList) {
                Asset asset = assetMapper.selectAssetById(Long.valueOf(a));
                contractSponsor.getAssetList().add(asset);
            }
        }

        return contractSponsor;
    }

    /**
     * 押金管理 详情
     */
    @Override
    public ContractSponsor selectContractSponsorByDepositId(Long id) {
        ContractSponsor contractSponsor = contractSponsorMapper.selectContractSponsorById(id);
        // 押金管理的决策依据
        String depositDecisionId = contractSponsor.getDepositDecisionId();
        if (StringUtils.isNotEmpty(depositDecisionId)) {
            List<String> ids = Arrays.asList(depositDecisionId.split(","));
            for (String i : ids) {
                CommonDecision decision1 = decisionMapper.selectCommonDecisionById(Long.valueOf(i));
                contractSponsor.getDepositDecisionList().add(decision1);
            }
        }

        return contractSponsor;
    }

    /**
     * 查询【合同发起】列表
     *
     * @param contractSponsor 【合同发起】
     * @return 【合同发起】
     */
    @Override
    public List<ContractSponsor> selectContractSponsorList(ContractSponsor contractSponsor) {
        List<ContractSponsor> list = contractSponsorMapper.selectContractSponsorList(contractSponsor);
        //合同过期时。押金管理类型为押金退费
        contractSponsorMapper.updateDepositType();
        return list;
    }


    //合同台账列表
    @Override
    public List<ContractSponsor> selectContractSponsorPigeonholeList(ContractSponsor contractSponsor) {
        contractSponsor.setStatus(3L);
        return contractSponsorMapper.selectContractSponsorList(contractSponsor);
    }

    /**
     * 合同预警
     *
     * @param contractSponsor 【合同预警】
     * @return 合同预警
     */
    @Override
    public List<ContractSponsor> selectContractSponsorWarningList(ContractSponsor contractSponsor) {
        contractSponsor.setWarning(1L);
        contractSponsor.setStatus(3L);
        contractSponsor.setPigeonhole(1L);
        return contractSponsorMapper.selectContractSponsorList(contractSponsor);
    }

    /**
     * 新增【合同发起】
     *
     * @param contractSponsor 【合同发起】
     * @return 结果
     */
    @Override
    public int insertContractSponsor(ContractSponsor contractSponsor, LoginUser loginUser) throws ParseException {
        int code = redisCache.getCacheObjectCode(LocalDate.now().format(Code.fmt) + "ckgr");
        addCode(code);
        contractSponsor.setContractSponsorNo(String.format("%s%s-%03d", "CKGR-HT", LocalDate.now().format(Code.fmt), code));
        contractSponsor.setCreatedAt(DateUtils.getNowDate());
        contractSponsor.setIsDeleted(0L);
        contractSponsor.setStatus(1L);
        contractSponsor.setAlterationState(1L);//未变更
        contractSponsor.setPigeonhole(1L);//未归档
        contractSponsor.setName(name(contractSponsor, loginUser.getDeptId()));
        int i = contractSponsorMapper.insertContractSponsor(contractSponsor);
        List<ContractBill> billList = billCopy(contractSponsor.getRentStateTime(), contractSponsor.getRentEndTime(),
                contractSponsor.getPaymentCycle(), contractSponsor.getYearlyRent(), contractSponsor.getId(), false);
        for (ContractBill c :billList){
            c.setDeptId(loginUser.getDeptId());
            billMapper.insertContractBill(c);
        }
        change(contractSponsor);
        return i;
    }

    /**
     * 合同名称
     */
    private String name(ContractSponsor contractSponsor,Long deptId){
        String assetName = "";
        String name = "";
        if (StringUtils.isNotEmpty(contractSponsor.getAssetName())){
            List<String> asList = Arrays.asList(contractSponsor.getAssetName().split(","));
            assetName = asList.get(0); //第一个资产名称
        }
        List<ContractSponsor> list = contractSponsorMapper.nameCheck(deptId, contractSponsor.getAssetName(), contractSponsor.getLesseeName());
        if (StringUtils.isNotEmpty(list)){
            return addOne(list.get(0).getName());
        }else {
           return name = assetName+"-"+contractSponsor.getLesseeName()+"-001";
        }



    }

    //获取合同名称最后数字进行+1
    public String addOne(String testStr){
        String[] strs = testStr.split("[^0-9]");//根据不是数字的字符拆分字符串
        String numStr = strs[strs.length-1];//取出最后一组数字
        if(numStr != null && numStr.length()>0){//如果最后一组没有数字(也就是不以数字结尾)，抛NumberFormatException异常
            int n = numStr.length();//取出字符串的长度
            int num = Integer.parseInt(numStr)+1;//将该数字加一
            String added = String.valueOf(num);
            n = Math.min(n, added.length());
            //拼接字符串
            return testStr.subSequence(0, testStr.length()-n)+added;
        }else{
            throw new NumberFormatException();
        }
    }
    /**
     * 修改【合同发起】
     *
     * @param contractSponsor 【合同发起】
     * @return 结果
     */
    @Override
    public int updateContractSponsor(ContractSponsor contractSponsor) throws ParseException {
        change(contractSponsor);
        contractSponsor.setUpdatedAt(DateUtils.getNowDate());
        billMapper.deleteContractBillByContract(contractSponsor.getId());
        List<ContractBill> billList = billCopy(contractSponsor.getRentStateTime(), contractSponsor.getRentEndTime(),
                contractSponsor.getPaymentCycle(), contractSponsor.getYearlyRent(), contractSponsor.getId(), false);
        for (ContractBill c :billList){
            c.setDeptId(contractSponsor.getCompanyId());
            billMapper.insertContractBill(c);
        }
        return contractSponsorMapper.updateContractSponsor(contractSponsor);
    }

    /**
     * 押金管理变更
     */
    @Override
    public int updateReceiptDeposit(ContractSponsor contractSponsor) {
        contractSponsor.setDepositType("2");
        contractSponsor.setDepositStatus(1L);
        return contractSponsorMapper.updateContractSponsor(contractSponsor);
    }

    //合同归档
    @Override
    public int updateContractSponsorPigeonhole(ContractSponsor contractSponsor) {
        contractSponsor.setUpdatedAt(DateUtils.getNowDate());
        return contractSponsorMapper.updateContractSponsor(contractSponsor);
    }

    /**
     * 批量删除【合同发起】
     *
     * @param ids 需要删除的【合同发起】主键
     * @return 结果
     */
    @Override
    public int deleteContractSponsorByIds(Long[] ids) {
        return contractSponsorMapper.deleteContractSponsorByIds(ids);
    }

    /**
     * 删除【合同发起】信息
     *
     * @param id 【合同发起】主键
     * @return 结果
     */
    @Override
    public int deleteContractSponsorById(Long id) {
        return contractSponsorMapper.deleteContractSponsorById(id);
    }

    /**
     * 合同变更
     *
     * @param contractSponsor 【合同变更】
     * @return 结果
     */
    @Override
    public int alterContractSponsor(ContractSponsor contractSponsor) throws ParseException {
        //合同审核通过可以变更
        if (contractSponsor.getStatus() != 3L) {
            throw new CustomException("合同发起审核通过后，才能进行变更操作");
        }
        //变更前原数据记录
        insetContractSponsorAlter(contractSponsor);
        contractSponsor.setAlterationState(2L);
        change(contractSponsor);
        contractSponsor.setUpdatedAt(DateUtils.getNowDate());
        contractSponsor.setIsAlter(2L);
        int i = contractSponsorMapper.updateContractSponsor(contractSponsor);
        //变更后数据
        ContractSponsorAlter alter = new ContractSponsorAlter();
        alter.setAlterPaymentCycle(contractSponsor.getPaymentCycle());
        alter.setAlterYearlyRent(contractSponsor.getYearlyRent());
        alter.setContractSponsor(contractSponsor.getId());

        billCopy(contractSponsor.getRentStateTime(), contractSponsor.getRentEndTime(),
                contractSponsor.getPaymentCycle(), contractSponsor.getYearlyRent(), contractSponsor.getId(), true);

        alterMapper.updateContractSponsorAlter(alter);
        return i;
    }


    //合同预警数量
    @Override
    public List<Map<String, Object>> warningCount(String letWay, Long companyId) {
        return contractSponsorMapper.warningCount(letWay, companyId);
    }

    /**
     * @param rentStateTime 租赁开始时间
     * @param rentEndTime   租赁结束时间
     * @param paymentCycle  付款周期 1-月，2-季，3-半年，4-年，5-一次性付清
     * @param yearlyRent    年租金
     * @return
     */
    @Override
    public List<ContractBill> bill(Date rentStateTime, Date rentEndTime, String paymentCycle, BigDecimal yearlyRent, Long contractSponsorId, Boolean isAlter) throws ParseException {
        ContractBill contractBill = new ContractBill();
        List<ContractBill> contractBills = new ArrayList<>();
        //是否为变更账单
        if (isAlter) {
            alterBill(contractSponsorId, rentEndTime, yearlyRent, paymentCycle, contractBill);
        } else {
            //获取天数
            long day = (rentEndTime.getTime() - rentStateTime.getTime()) / (24 * 60 * 60 * 1000);
            //期数
            int period = periods(paymentCycle, day);
            //租赁金额
            DecimalFormat df = new DecimalFormat("0.0");
            String format = df.format((float) day / 365);
            BigDecimal money = new BigDecimal(format);
            BigDecimal p = new BigDecimal(period);
            BigDecimal multiply = yearlyRent.multiply(money);
            BigDecimal divide = multiply.divide(p, BigDecimal.ROUND_CEILING);

            for (int i = 0; i < period; i++) {
                if (period == 1) {
                    contractBill.setRentMoney(divide);
                    contractBill.setContractSponsorId(contractSponsorId);
                    contractBill.setRentPeriods((long) i + 1);
                    contractBill.setRentStateTime(rentStateTime);
                    contractBill.setRentEndTime(rentEndTime);
                    contractBill.setPayableStateTime(rentStateTime);
                    contractBill.setPayableEndTime(rentStateTime);
                    contractBills.add(contractBill);
                    if (contractSponsorId != null) {
                        billMapper.insertContractBill(contractBill);
                    }
                    break;
                } else {
                    contractBill.setRentMoney(divide);
                    contractBill.setContractSponsorId(contractSponsorId);
                    contractBill.setRentPeriods((long) i + 1);
                    installmentTime(rentStateTime, rentEndTime, paymentCycle, contractBill, i);
                    if (contractSponsorId != null) {
                        billMapper.insertContractBill(contractBill);
                    }
                    contractBills.add(contractBill);
                }

            }
        }

        if (contractSponsorId != null) {
            ContractBill bill = new ContractBill();
            bill.setContractSponsorId(contractSponsorId);
            return billMapper.selectContractBillList(bill);
        }


        return contractBills;
    }

    public List<ContractBill> billCopy(Date rentStateTime, Date rentEndTime, String paymentCycle, BigDecimal yearlyRent, Long contractSponsorId, Boolean isAlter) throws ParseException {
        ContractBill contractBill = new ContractBill();
        List<ContractBill> contractBills = new ArrayList<>();
        //是否为变更账单
        if (isAlter) {
            //获取剩余租金,删除剩余期数
            Map<String,Object>map=getSurplusMoney(rentStateTime,contractSponsorId);
            BigDecimal surplusMoney=(BigDecimal)map.get("resultMoney");
            contractBills=map.containsKey("list")&&map.get("list")!=null? (List<ContractBill>)map.get("list"): new ArrayList<>();
            //租金处理
            List<ContractBill> rentTime = getRentTime(rentStateTime, rentEndTime, paymentCycle, contractSponsorId, surplusMoney);
            contractBills.addAll(rentTime);

        } else {
            //获取
            contractBills = getRentTime(rentStateTime, rentEndTime, paymentCycle, contractSponsorId, yearlyRent);
        }

//        if (contractSponsorId != null) {
//            ContractBill bill = new ContractBill();
//            bill.setContractSponsorId(contractSponsorId);
//            return billMapper.selectContractBillList(bill);
//        }
//        for (int i = 0; i < contractBills.size(); i++) {
//            ContractBill contractBill1 = contractBills.get(i);
//            contractBill1.setRentPeriods(Long.valueOf(i+1));
//            billMapper.insertContractBill(contractBill1);
//        }

        return contractBills;
    }

    private Map<String,Object> getSurplusMoney(Date rentStateTime, Long contractSponsorId) {
        Map<String,Object> map=new HashMap<>();
        ContractBill bill = new ContractBill();
        bill.setContractSponsorId(contractSponsorId);
        BigDecimal resultMoney = new BigDecimal("0");
        List<ContractBill> contractBills = billMapper.selectContractBillList(bill);
        List<ContractBill> contractBills1=contractBills.stream().filter(obj->obj.getRentStateTime().getTime()<=rentStateTime.getTime()).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(contractBills1)){

            for (ContractBill contractBill : contractBills1) {
                BigDecimal countMoney = contractBill.getRentMoney();
                resultMoney=resultMoney.add(countMoney);
            }
            List<Long> ids = contractBills.stream().map(ContractBill::getId).collect(Collectors.toList());
            billMapper.deleteContractBillByIds(ids.toArray(new Long[]{}));
            contractBills.removeAll(contractBills1);


        }
        map.put("resultMoney",resultMoney);
        map.put("list",contractBills1);

        return map;
    }

    /**
     * 获取房租缴费日期
     *
     * @param rentStateTime 租赁开始时间
     * @param rentEndTime   租赁结束时间
     * @param paymentCycle  付款周期 1-月，2-季，3-半年，4-年，5-一次性付清
     * @return
     */
    private List<ContractBill> getRentTime(Date rentStateTime, Date rentEndTime, String paymentCycle, Long contractSponsorId, BigDecimal yearlyRent) {
        List<ContractBill> list = new ArrayList<>();

        LocalDate staLocalDate = DateUtils.toLocalDate(rentStateTime);
        LocalDate endLocalDate = DateUtils.toLocalDate(rentEndTime);

        //添加第一期
        ContractBill contractBill = new ContractBill();
        contractBill.setContractSponsorId(contractSponsorId);
//        contractBill.setRentEndTime(DateUtils.toDate(staLocalDate.with(TemporalAdjusters.lastDayOfMonth())));
        contractBill.setRentEndTime(DateUtils.toDate(staLocalDate.plusMonths(1L).minusDays(1L)));
        contractBill.setRentStateTime(rentStateTime);
        contractBill.setPayableStateTime(rentStateTime);
        contractBill.setPayableEndTime(rentStateTime);
        contractBill.setRentPeriods(1L);
        list.add(contractBill);
        int monthDivide=0;
        int periodsNum=0;
        int endValue = endLocalDate.getMonth().getValue();
        int staValue1 = staLocalDate.getMonth().getValue();
        int monthNum = (endLocalDate.getYear()-staLocalDate.getYear()-1)*12+(12-staValue1+1)+endValue;
        //不同月
        if (monthNum>0){
            switch (paymentCycle) {
                case "1":
                    monthDivide=1;

                    list=updatePaymentCycle(contractSponsorId,list,monthDivide,endLocalDate,monthNum,yearlyRent,staLocalDate);
                    break;
                case "2":
                    monthDivide=3;
                    //获取期数
//                    contractBill.setRentEndTime(DateUtils.toDate(staLocalDate.plusMonths(monthDivide).with(TemporalAdjusters.lastDayOfMonth()).minusMonths(1L)));
                    contractBill.setRentEndTime(DateUtils.toDate(staLocalDate.plusMonths(monthDivide).minusDays(1L)));
                    periodsNum= new BigDecimal(String.valueOf(monthNum)).divide(new BigDecimal(String.valueOf(monthDivide)),0, BigDecimal.ROUND_UP).intValue();
                    list=updatePaymentCycle(contractSponsorId,list,monthDivide,endLocalDate,periodsNum-1,yearlyRent,staLocalDate);
                    break;
                case "3":
                    monthDivide=6;
//                    contractBill.setRentEndTime(DateUtils.toDate(staLocalDate.plusMonths(monthDivide).with(TemporalAdjusters.lastDayOfMonth()).minusMonths(1L)));
                    contractBill.setRentEndTime(DateUtils.toDate(staLocalDate.plusMonths(monthDivide).minusDays(1L)));
                    periodsNum= new BigDecimal(String.valueOf(monthNum)).divide(new BigDecimal(String.valueOf(monthDivide)),0, BigDecimal.ROUND_UP).intValue();
                    list=updatePaymentCycle(contractSponsorId,list,monthDivide,endLocalDate,periodsNum-1,yearlyRent,staLocalDate);
                    break;
                case "4":
                    monthDivide=12;
//                    contractBill.setRentEndTime(DateUtils.toDate(staLocalDate.plusMonths(monthDivide).with(TemporalAdjusters.lastDayOfMonth()).minusMonths(1L)));
                    contractBill.setRentEndTime(DateUtils.toDate(staLocalDate.plusMonths(monthDivide).minusDays(1L)));
                    periodsNum= new BigDecimal(String.valueOf(monthNum)).divide(new BigDecimal(String.valueOf(monthDivide)),0, BigDecimal.ROUND_UP).intValue();
                    list=updatePaymentCycle(contractSponsorId,list,monthDivide,endLocalDate,periodsNum-1,yearlyRent,staLocalDate);
                    break;
                case "5":
                    contractBill.setRentEndTime(rentEndTime);
                    contractBill.setRentMoney(yearlyRent);
                    break;
            }
        }else{
            contractBill.setRentMoney(yearlyRent);
        }

        return list;
    }

    /**
     *
     * @param list
     * @param monthDivide 每期月数;
     * @param endLocalDate 租期结束日期
     * @param monthNum  获取期数
     * @param yearlyRent  总租金
     * @param staLocalDate  租期开始时间
     * @return
     */
    private List<ContractBill> updatePaymentCycle(Long contractSponsorId,List<ContractBill> list, int monthDivide, LocalDate endLocalDate,
                                                  int monthNum, BigDecimal yearlyRent,LocalDate staLocalDate) {

        //每期金额
        BigDecimal bigDecimal = yearlyRent.divide(new BigDecimal(String.valueOf(monthNum)),2, BigDecimal.ROUND_UP);
        list.get(0).setRentMoney(bigDecimal);
        for (int i = 0; i < monthNum-1; i++) {
            ContractBill bill=new ContractBill();
            bill.setPayableStateTime(DateUtils.toDate(staLocalDate.with(TemporalAdjusters.firstDayOfMonth())));
            bill.setPayableStateTime(DateUtils.toDate(staLocalDate.plusMonths(monthDivide)));
//            bill.setPayableEndTime(DateUtils.toDate(staLocalDate.plusMonths(monthDivide).with(TemporalAdjusters.lastDayOfMonth())));
            bill.setPayableEndTime(DateUtils.toDate(DateUtils.toLocalDate(bill.getPayableStateTime()).plusMonths(1L).minusDays(1L)));

            staLocalDate=staLocalDate.plusMonths(monthDivide);//每期月份
            Long rentPeriods=1L;
            bill.setRentMoney(bigDecimal);
            bill.setContractSponsorId(contractSponsorId);

            if (monthDivide == 1){
//                bill.setRentStateTime(DateUtils.toDate(DateUtils.toLocalDate(bill.getPayableStateTime()).plusMonths(1L)));
                bill.setRentStateTime(DateUtils.toDate(staLocalDate));
            }else {
//                bill.setRentStateTime(DateUtils.toDate(DateUtils.toLocalDate(bill.getPayableEndTime()).plusDays(1L)));
                bill.setRentStateTime(DateUtils.toDate(staLocalDate));
            }



            if (i==monthNum-2){
                bill.setRentEndTime(DateUtils.toDate(endLocalDate));
            }else{
                if (monthDivide == 1){
//                    bill.setRentEndTime(DateUtils.toDate(DateUtils.toLocalDate(bill.getPayableEndTime()).plusDays(1L)));
                    bill.setRentEndTime(DateUtils.toDate(DateUtils.toLocalDate(bill.getRentStateTime()).plusMonths(monthDivide).minusDays(1L)));
                }else {
//                    bill.setRentEndTime(DateUtils.toDate(staLocalDate.plusMonths(monthDivide).with(TemporalAdjusters.lastDayOfMonth()).plusDays(1L)));
                    bill.setRentEndTime(DateUtils.toDate(DateUtils.toLocalDate(bill.getRentStateTime()).plusMonths(monthDivide).minusDays(1L)));
                }

            }



            bill.setRentPeriods(rentPeriods+i+1);
            list.add(bill);
        }

        return list;
    }


    //变更时账单
    private void alterBill(Long contractSponsorId, Date rentEndTime, BigDecimal yearlyRent, String paymentCycle, ContractBill contractBill) throws ParseException {
        //获取当前期数
        ContractBill bill = billMapper.selectContractBillPeriod(contractSponsorId);
        Long periods = bill.getRentPeriods();
        Long maxPeriods = bill.getMaxPeriods();

        Date endTime = bill.getRentEndTime();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(endTime);
        calendar.add(Calendar.DATE, 1);
        Date time = calendar.getTime(); // 开始时间

        //获取天数
        long day = (rentEndTime.getTime() - time.getTime()) / (24 * 60 * 60 * 1000);
        //期数
        int period = periods(paymentCycle, day);

        //金额
        BigDecimal countMoney = bill.getCountMoney();
        BigDecimal subtract = yearlyRent.subtract(countMoney);
        DecimalFormat df = new DecimalFormat("0.0");
        String format = df.format((float) day / 365);
        BigDecimal money = new BigDecimal(format);
        BigDecimal p = new BigDecimal(period);
        BigDecimal multiply = subtract.multiply(money);
        BigDecimal divide = multiply.divide(p, BigDecimal.ROUND_CEILING); //每期金额

        for (long a = periods + 1; a <= maxPeriods; a++) {
            billMapper.deleteContractBillByContractId(contractSponsorId, a);
        }

        for (int i = 0; i < period; i++) {
            contractBill.setRentMoney(divide);
            contractBill.setContractSponsorId(contractSponsorId);
            contractBill.setRentPeriods(periods + 1);
            installmentTime(time, rentEndTime, paymentCycle, contractBill, i);
            billMapper.insertContractBill(contractBill);
            periods++;
        }
    }

    /**
     * 审核回调
     *
     * @param
     * @return
     */
    @Override
    public int callBack(Long id, Long status, String oaFile) {
        ContractSponsor contractSponsor = contractSponsorMapper.selectContractSponsorById(id);
        contractSponsor.setOaFile(oaFile);
        contractSponsor.setStatus(status);
        contractSponsor.setUpdatedAt(DateUtils.getNowDate());
        contractSponsor.setDepositStatus(1L);
        contractSponsor.setDepositType("1");
        return contractSponsorMapper.updateContractSponsor(contractSponsor);
    }

    //押金审核回调
    @Override
    public int callBackDeposit(Long id, String oaFile, BigDecimal cashPledge,String depositRemark,
                               String depositDecisionId,Long depositStatus) {
        ContractSponsor contractSponsor = contractSponsorMapper.selectContractSponsorById(id);
        if (depositStatus == 3L) {
            contractSponsor.setBackTime(DateUtils.getNowDate());
            contractSponsor.setOaDepositFile(oaFile);
            contractSponsor.setCashPledge(cashPledge);
            contractSponsor.setDepositRemark(depositRemark);
            contractSponsor.setDepositDecisionId(depositDecisionId);
        }
        contractSponsor.setDepositStatus(depositStatus);
        return contractSponsorMapper.updateContractSponsor(contractSponsor);
    }

    @Override
    public int callBackDepositPayee(Long id, String oaFile, BigDecimal depositPayeeMoney, String depositPayeeNum,
                                    String depositPayeeFile, Long depositPayeeStatus, Date depositPayeeTime) {
        ContractSponsor contractSponsor = contractSponsorMapper.selectContractSponsorById(id);
        if (depositPayeeStatus == 3L){
            contractSponsor.setOaDepositPayeeFile(oaFile);
            contractSponsor.setDepositPayeeTime(depositPayeeTime);
            contractSponsor.setDepositPayeeFile(depositPayeeFile);
            contractSponsor.setDepositPayeeNum(depositPayeeNum);
            contractSponsor.setDepositPayeeMoney(depositPayeeMoney);
        }
        contractSponsor.setDepositPayeeStatus(depositPayeeStatus);
        return contractSponsorMapper.updateContractSponsor(contractSponsor);
    }

    @Override
    public int callBackDepositRefund(Long id, String oaFile, BigDecimal depositRefundMoney, String depositRefundNum,
                                     String depositRefundFile, Long depositRefundStatus, Date depositRefundTime) {
        ContractSponsor contractSponsor = contractSponsorMapper.selectContractSponsorById(id);
        if (depositRefundStatus == 3L){
            contractSponsor.setOaDepositRefundFile(oaFile);
            contractSponsor.setDepositRefundTime(depositRefundTime);
            contractSponsor.setDepositRefundFile(depositRefundFile);
            contractSponsor.setDepositRefundNum(depositRefundNum);
            contractSponsor.setDepositRefundMoney(depositRefundMoney);
        }
        contractSponsor.setDepositRefundStatus(depositRefundStatus);
        return contractSponsorMapper.updateContractSponsor(contractSponsor);
    }


    @Override
    public List<ContractSponsor> selectContractSponsorAllocation(ContractSponsor contractSponsor) {
        List<ContractSponsor> list = contractSponsorMapper.selectContractSponsorList(contractSponsor);
        for (ContractSponsor c : list){
            c.setContractBill(billMapper.selectLast(c.getId()));
        }
        return list;
    }

    @Override
    public ContractSponsor selectContractSponsorAllocationById(Long id) {
        ContractSponsor contractSponsor = contractSponsorMapper.selectContractSponsorById(id);

        //账期信息
        ContractBill bill = new ContractBill();
        bill.setContractSponsorId(id);
        List<ContractBill> billList = billMapper.selectContractBillList(bill);
        for (ContractBill c : billList){
            //减免信息列表
            ContractSponsorCredit credit = new ContractSponsorCredit();
            credit.setContractSponsorId(id);
            credit.setRentPeriods(c.getRentPeriods());
            List<ContractSponsorCredit> creditList = creditMapper.selectContractSponsorCreditList(credit);
            if (StringUtils.isNotEmpty(creditList))
            c.getCreditList().addAll(creditList);

            //租金分配收款
            AssetReceiptAllocation allocation = new AssetReceiptAllocation();
            allocation.setContractSponsorId(id);
            allocation.setRentPeriods(c.getRentPeriods());
            List<AssetReceiptAllocation> list = allocationMapper.selectAssetReceiptAllocationList(allocation);
            if (StringUtils.isNotEmpty(list))
            c.getAllocationList().addAll(list);
        }
        contractSponsor.setContractBillList(billList);

        return contractSponsor;
    }

    @Override
    public BigDecimal noAllotMoney(Long id) {
        return contractSponsorMapper.noAllotMoney(id);
    }

    /**
     * 总计租率
     * @param companyId
     * @return
     */
    @Override
    public Map<String, Object> getTotalRentalRate(Long companyId) {
        // 根据公司id查询所有账面
        List<Map<String, Object>> list = bookValueMapper.selectAssetIdByCompanyId(companyId);
        BigDecimal rate_total = new BigDecimal(0);
      /*  // 所有资产id集合
        List<Integer> assetIds = new ArrayList<>();
        // 账面id映射资产id集合
        Map<Long, List<Integer>> bookValueMap = new HashMap<>();
        for (Map m:list) {
            if (m != null) {
                String assetId = (String)m.get("asset_id");
                if (!StrUtil.isBlank(assetId)) {
                    if (assetId.contains(",")) {
                        String[] assetIdArr = assetId.split(",");
                        List<Integer> assetSubIds = Arrays.stream(assetIdArr).map(Integer::parseInt).collect(Collectors.toList());
                        assetIds.addAll(assetSubIds);
                        bookValueMap.put((Long)m.get("id"), assetSubIds);
                    } else {
                        int assetIdInt = Integer.parseInt(assetId);
                        assetIds.add(assetIdInt);
                        List<Integer> subList = new ArrayList<>();
                        subList.add(assetIdInt);
                        bookValueMap.put((Long)m.get("id"), subList);
                    }
                }
            }
        }

        // 计租账面关联资产关联的合同租赁面积 x计租天数
        List<Map<String, Object>> contractList = contractSponsorMapper.selectRentalAreaMulDays(assetIds);
        // 资产id映射 乘积
        Map<Integer, Long> rentalAreaMap = new HashMap<>();
        for ( Map list:contractList) {
            if (list != null) {
                list.get("asset_id")
            }
        }
        // 账面价值关联资产总可租面积 x 总时长
        List<Map<String, Object>> assetList = assetMapper.selectLettableArea(assetIds);*/

        for (Map m:list) {
            if (m != null) {
                String assetId = (String)m.get("asset_id");
                if (!StrUtil.isBlank(assetId)) {
                    List<Integer> assetIds = new ArrayList<>();
                    if (assetId.contains(",")) {
                        String[] assetIdArr = assetId.split(",");
                        assetIds = Arrays.stream(assetIdArr).map(Integer::parseInt).collect(Collectors.toList());
                    } else {
                        assetIds.add(Integer.parseInt(assetId));
                    }
                    Map<String, Object> total1 = contractSponsorMapper.selectRentalAreaMulDays(assetIds);
                    Map<String, Object> total2 = assetMapper.selectLettableArea(assetIds);

                    if (total2 != null && total1 != null && new BigDecimal(total2.get("total").toString()).compareTo(BigDecimal.ZERO)>0) {
                        BigDecimal div = new BigDecimal(total1.get("total").toString()).divide(new BigDecimal(total2.get("total").toString()), 4, BigDecimal.ROUND_DOWN);
                        rate_total = rate_total.add(div);
                    }
                }
            }
        }
        Map<String, Object> res = new HashMap<>();
        res.put("rate", rate_total.doubleValue());
        return res;
    }

    /**
     * 总出租率: 已出租房源租租赁面积累加/总房源可租面积累加
     * @param companyId
     * @return
     */
    @Override
    public Map<String, Object> getTotalLettingRate(Long companyId) {
        return contractSponsorMapper.selectTotalLettingRate(companyId);
    }

    /**
     * 总计租均价: 租金总额/∑(计租面积 x 计租天数)
     * @param companyId
     * @return
     */
    @Override
    public Map<String, Object> getAverageRentalPrice(Long companyId) {
        return contractSponsorMapper.selectAverageRentalPrice(companyId);
    }

    /**
     * 总平效: Σ日租金单价*计租天数/(总可出租面积 x 总时长)
     * @param companyId
     * @return
     */
    @Override
    public Map<String, Object> getTotalUtilityEquality(Long companyId) {
        return contractSponsorMapper.selectTotalUtilityEquality(companyId);
    }

    /**
     * 账面平效排行榜
     */
    public List<Map<String, Object>> getBookValueUtilityEqualityRanking(Long companyId) {
        return contractSponsorMapper.selectBookValueUtilityEqualityRanking(companyId);
    }

    /**
     * 总收益: 总可租面积 x 计租率 x 计租均价 x 天数
     * @param companyId
     * @return
     */
    @Override
    public Map<String, Object> getTotalEarnings(Long companyId) {
        // 总可用面积
        Map<String, Object> totalUsableArea = contractSponsorMapper.selectTotalUsableArea(companyId);
        // 总计租率
        Map<String, Object> totalLettingRate = getTotalLettingRate(companyId);
        // 计租均价
        Map<String, Object> averageRentalPrice = getAverageRentalPrice(companyId);
        // 总时长
        int days = getDays();
        Double totalEarnings = new BigDecimal(totalUsableArea.get("total").toString()).multiply(new BigDecimal(totalLettingRate.get("rate").toString())).
                multiply(new BigDecimal(averageRentalPrice.get("price").toString())).multiply(new BigDecimal(days)).setScale(2, RoundingMode.DOWN).doubleValue();
        Map<String, Object> res = new HashMap<>();
        res.put("totalEarnings", totalEarnings);
        return res;
    }

    /**
     * 逾期金额 + 逾期租客数量 + 收缴率 + 逾期率 + 逾期金额占比
     * @param companyId
     * @return
     */
    @Override
    public Map<String, Object> getRentCollection(Long companyId) {
        Map<String, Object> res = contractSponsorMapper.selectRentCollection(companyId);
        Map<String, Object> countOverdueLessee = contractSponsorMapper.selectCountOverdueLessee(companyId);
        res.put("count_overdue_lessee", countOverdueLessee.get("count_overdue_lessee"));
        return res;
    }

    /**
     * 开票金额和减免金额
     */
    @Override
    public Map<String, Object> getInvoiceAndCredit(Long companyId) {
        return contractSponsorMapper.selectInvoiceAndCredit(companyId);
    }

    /**
     * 逾期租户比率
     * @param companyId
     * @return
     */
    @Override
    public Map<String, Object> getCountOverdueLesseeRate(Long companyId) {
        return contractSponsorMapper.selectCountOverdueLesseeRate(companyId);
    }

    /**
     * 逾期率排名
     * @param companyId
     * @return
     */
    @Override
    public List<Map<String, Object>> getOverdueLesseeRateRanking(Long companyId) {
        return contractSponsorMapper.selectOverdueLesseeRateRanking(companyId);
    }

    /**
     * 逾期金额排名
     * @param companyId
     * @return
     */
    @Override
    public List<Map<String, Object>> getOverdueLesseeAmountRanking(Long companyId) {
        return contractSponsorMapper.selectOverdueLesseeAmountRanking(companyId);
    }

    /**
     * 租户总已缴租金排名
     * @param companyId
     * @return
     */
    @Override
    public List<Map<String, Object>> getCaptureLesseeAmountRanking(Long companyId) {
        return contractSponsorMapper.selectCaptureLesseeAmountRanking(companyId);
    }

    /**
     * 总效益流失率
     * @param companyId
     * @return
     */
    @Override
    public Map<String, Object> getTotalRateOfLossOfBenefits(Long companyId) {
        return contractSponsorMapper.selectTotalRateOfLossOfBenefits(companyId);
    }

    /**
     * 租金流失总额
     * @param companyId
     * @return
     */
    @Override
    public Map<String, Object> getTotalRentLoss(Long companyId) {
        return contractSponsorMapper.selectTotalRentLoss(companyId);
    }

    /**
     * 创建时间排前10的合同
     * @param companyId
     * @return
     */
    @Override
    public List<ContractSponsor> getTop10ByCreateAt(Long companyId) {
        return contractSponsorMapper.selectTop10ByCreateAt(companyId);
    }

    /**
     * 合同分类 + 出租类型
     * @param companyId
     * @return
     */
    @Override
    public List<Map<String, Object>> getContractSponsorType(Long companyId) {
        return contractSponsorMapper.selectContractSponsorType(companyId);
    }

    /**
     * 租金收缴 近12个月：待付（应收）
     */
    public List<Map<String, Object>> getContractSponsorReceivable(Long companyId) {
        List<Map<String, Object>> list = contractSponsorMapper.selectContractSponsorReceivable(companyId);
        return new AssetMonthServiceImpl().packageData(list, "date", "money");
    }

    /**
     * 租金收缴 近12个月：已收（实收）
     */
    public List<Map<String, Object>> getContractSponsorReceipts(Long companyId) {
        List<Map<String, Object>> list = contractSponsorMapper.selectContractSponsorReceipts(companyId);
        return new AssetMonthServiceImpl().packageData(list, "date", "money");
    }

    /**
     * 租金收缴 近12个月：减免
     */
    public List<Map<String, Object>> getContractSponsorCredit(Long companyId) {
        List<Map<String, Object>> list = contractSponsorMapper.selectContractSponsorCredit(companyId);
        return new AssetMonthServiceImpl().packageData(list, "date", "money");
    }

    /**
     * 营业外收入与支出
     */
    public Map<String, Object> getIncomingsAndOutgoings(Long companyId) {
        List<Map<String, Object>> income = contractSponsorMapper.selectIncome(companyId);
        List<Map<String, Object>> contract = contractMapper.selectTotalAmount(companyId);
        Map<String, Object> res = new HashMap<>();
        res.put("house", 0);
        res.put("land", 0);
        res.put("maintain", new BigDecimal(0));
        res.put("project", 0);
        for (Map i:income) {
            if (i.get("contract_type") == null || i.get("house_rent") == null) {
                continue;
            }
            if (Objects.equals(i.get("contract_type"), "1")) {
                res.put("house", i.get("house_rent"));
            }
            if (Objects.equals(i.get("contract_type"), "2")) {
                res.put("land", i.get("house_rent"));
            }
        }
        for (Map c:contract) {
            if (c.get("type") != null || c.get("total_amount") != null) {
                String amountStr = c.get("type").toString();
                switch (amountStr) {
                    case "1":
                    case "2":
//                        ((BigDecimal)item.computeIfAbsent("maintain", val -> new BigDecimal(0))).add(new BigDecimal(amountStr));
                        BigDecimal maintain = ((BigDecimal)res.get("maintain")).add(new BigDecimal(c.get("total_amount").toString()));
                        res.put("maintain", maintain);
                        break;
                    case "3":
                        res.put("project", new BigDecimal(c.get("total_amount").toString()));
                }
            }
        }
        return res;
    }

    /**
     * 查询出租情况啊（出租面积+出租金额+出租率+收缴率）
     */
    @Override
    public Map<String, Object> getRentDetail(Long companyId) {
        Map<String, Object> res = new HashMap<>();
        Map<String, Object> map = contractSponsorMapper.selectRentAreaAndMoney(companyId);
        mapGetIfNullPut(map, res, "total_rent_area");
        mapGetIfNullPut(map, res, "total_rent_rental");
        map = contractSponsorMapper.selectRentRate(companyId);
        mapGetIfNullPut(map, res, "rent_rate");
        map = contractSponsorMapper.selectCaptureRate(companyId);
        mapGetIfNullPut(map, res, "capture_rate");
        return res;
    }

    void mapGetIfNullPut(Map<String, Object> map, Map<String, Object> res, String field) {
        if (map.get(field) != null) {
            res.put(field, map.get(field));
        } else {
            res.put(field, 0);
        }
    }

    /**
     * 导出excel所需的出租资产数据
     * @param companyId
     * @return
     */
    @Override
    public List<ContractSponsorExportVo> idleList(@Param("companyId") Long companyId) {
        List<Map<String, Object>> list = contractSponsorMapper.selectListByExportExcel(companyId);
        List<ContractSponsorExportVo> res = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            ContractSponsorExportVo info = new ContractSponsorExportVo();
            Map<String, Object> item = list.get(i);
            info.setIdx(i+1);
            info.setPropertyOwnerName(item.get("property_owner_name") != null ? item.get("property_owner_name").toString() : "");
            info.setBusinessEntity(item.get("business_entity") != null ? item.get("business_entity").toString() : "");
            info.setAssetNo(item.get("business_entity") != null ? item.get("business_entity").toString() : "");
            info.setAssetNo(item.get("asset_no") != null ? item.get("asset_no").toString() : "");
            info.setName(item.get("name") != null ? item.get("name").toString() : "");
            info.setCategory(item.get("category") != null ? item.get("category").toString() : "");
            info.setRentArea(item.get("rent_area") != null ? item.get("rent_area").toString() : "");
            info.setAddress(item.get("address") != null ? item.get("address").toString() : "");
            info.setLesseeName(item.get("lessee_name") != null ? item.get("lessee_name").toString() : "");
            info.setBeginTime(item.get("rent_state_time") != null ? item.get("rent_state_time").toString() : "");
            info.setEndTime(item.get("rent_end_time") != null ? item.get("rent_end_time").toString() : "");
            info.setTenantryDays(item.get("tenancy") != null ? item.get("tenancy").toString() : "");
            info.setYearlyRent(item.get("yearly_rent") != null ? item.get("yearly_rent").toString() : "");
            info.setMonthlyRent(item.get("monthly_rent") != null ? item.get("monthly_rent").toString() : "");
            info.setRentMoneyTotal(item.get("total_rent_money") != null ? item.get("total_rent_money").toString() : "");
            info.setReceiptMoneyTotal(item.get("total_money") != null ? item.get("total_money").toString() : "");
            info.setCreditAmountTotal(item.get("total_credit_amount") != null ? item.get("total_credit_amount").toString() : "");
            info.setUncollectedTotal(item.get("sub_val") != null ? item.get("sub_val").toString() : "");
            info.setCreatedAt(item.get("created_at") != null ? item.get("created_at").toString() : "");
            info.setInvoiceAmount(item.get("invoice_amount") != null ? item.get("invoice_amount").toString() : "");
            info.setAllocationTime(item.get("allocation_time") != null ? item.get("allocation_time").toString() : "");
            info.setMoney(item.get("money") != null ? item.get("money").toString() : "");
            info.setIsCredit(item.get("is_rent_free") != null ? item.get("is_rent_free").toString() : "");
            res.add(info);
        }
        return res;
    }


    /**
     * 生成编码
     */
    private synchronized void addCode(int code) {
        redisCache.setCacheObject(LocalDate.now().format(Code.fmt) + "ckgr", code + 1);
    }

    private synchronized void addAlterCode(int code) {
        redisCache.setCacheObject(LocalDate.now().format(Code.fmt) + "alter", code + 1);
    }

    private void change(ContractSponsor contractSponsor) {
        //附件
        enclosureMapper.deleteContractSponsorEnclosureByContractId(contractSponsor.getId());
        if (StringUtils.isNotEmpty(contractSponsor.getEnclosureList())) {
            contractSponsor.getEnclosureList().forEach(item -> {
                item.setCreatedAt(DateUtils.getNowDate());
                item.setContractSponsorId(contractSponsor.getId());
                item.setState("1");//上传成功
                enclosureMapper.insertContractSponsorEnclosure(item);
            });
        }
    }

    //变更记录
    private void insetContractSponsorAlter(ContractSponsor contractSponsor) {
        ContractSponsorAlter alter = new ContractSponsorAlter();
        ContractSponsor sponsor = contractSponsorMapper.selectContractSponsorById(contractSponsor.getId());
        alter.setContractSponsor(sponsor.getId());
        alter.setAlterExplain(contractSponsor.getAlterExplain());
        alter.setYearlyRent(sponsor.getYearlyRent());
        alter.setPaymentCycle(sponsor.getPaymentCycle());
        alter.setAlterTime(DateUtils.getNowDate());
        alterMapper.insertContractSponsorAlter(alter);
    }

    //账单期数  付款周期 1-月，2-季，3-半年，4-年，5-一次性付清
    private int periods(String paymentCycle, Long day) {
        int period = 0;
        if (("1").equals(paymentCycle)) {
            period = (int) Math.ceil((double) day / 30);
        } else if (("2").equals(paymentCycle)) {
            period = (int) Math.ceil((double) day / (30 * 3));
        } else if (("3").equals(paymentCycle)) {
            period = (int) Math.ceil((double) day / (30 * 6));
        } else if (("4").equals(paymentCycle)) {
            period = (int) Math.ceil((double) day / 365);
        } else {
            period = 1;
        }
        return period;
    }

    //账单时间
    private void installmentTime(Date rentStateTime, Date rentEndTime, String paymentCycle, ContractBill contractBill, int d) throws ParseException {
        int s = 0;
        if (("1").equals(paymentCycle)) {
            s = 1;
        } else if (("2").equals(paymentCycle)) {
            s = 3;
        } else if (("3").equals(paymentCycle)) {
            s = 6;
        } else if (("4").equals(paymentCycle)) {
            s = 12;
        } else {
            s = 1;
        }
        //开始时间
        //rangeToList （1.开始时间，2.结束时间.3.生成模式（Month,每月）4.间隔：1）
        List<DateTime> startTimes = DateUtil.rangeToList(rentStateTime, rentEndTime, DateField.MONTH, s);

        //时间计算
        Calendar cld = Calendar.getInstance();
        //放入需要计算的时间
        cld.setTime(rentStateTime);
        //时间计算纬度，（Month月，每次增加数量1）
        cld.add(Calendar.MONTH, s);
        //结束时间
        //rangeToList （1.开始时间，2.结束时间.3.生成模式（Month,每月）4.间隔：1）
        List<DateTime> endTimes = DateUtil.rangeToList(cld.getTime(), rentEndTime, DateField.MONTH, s);
        int i = 0;
        //遍历
        for (DateTime time : endTimes) {

            Calendar cld1 = Calendar.getInstance();
            //放入需要计算的时间
            cld1.setTime(endTimes.get(i));
            //时间计算纬度，（DAY填，每次增加数量-1）
            cld1.add(Calendar.DAY_OF_YEAR, -1);
            //把计算后时间放入对应集合位置
            endTimes.set(i, new DateTime(cld1.getTime()));
            i++;
        }
        //判断集合中是否存在结束时间
        boolean contains = endTimes.contains(new DateTime(rentEndTime));
        //不存在，添加
        if (!contains) {
            endTimes.add(new DateTime(rentEndTime));
        }
        contractBill.setRentStateTime(startTimes.get(d));
        contractBill.setRentEndTime(endTimes.get(d));
        if (d == 0) {
            contractBill.setPayableStateTime(startTimes.get(0));
            contractBill.setPayableEndTime(startTimes.get(0));
        } else {
            contractBill.setPayableStateTime(startTimes.get(d - 1));
            contractBill.setPayableEndTime(endTimes.get(d - 1));
        }

    }

    // 获取从1月1日到当前的天数
    public int getDays() {
        LocalDate today = LocalDate.now();
        LocalDate startOfYear = LocalDate.of(today.getYear(), 1, 1);
        Period period = Period.between(startOfYear, today);
        return period.getDays();
    }

}
